xquery version "1.0" encoding "UTF-8";

module namespace xsgi = "http://www.webcomposite.com/xsgi";

import module namespace request="http://exist-db.org/xquery/request";
import module namespace json="http://www.json.org";

declare variable $xsgi:version := 0.1 ;

declare function xsgi:forward($path){
	<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
		<forward url="{$path}"/>
	</dispatch>
};

declare function xsgi:redirect($path){
	<dispatch xmlns="http://exist.sourceforge.net/NS/exist">
		<redirect url="{$path}"/>
	</dispatch>
};

declare function xsgi:invoke($prefix,$ns,$module,$xpath,$model as xs:string){
	let $m := util:eval($model)
	let $xquery := concat("import module namespace ",$prefix,"='",$ns,"' at '",$module,"';",$xpath)
	let $debug  := request:get-parameter('debug',())
	let $result := util:eval-inline($m,$xquery)
	return
		if($debug) then
	       <xsgi:response><xsgi:env>{$result[1]}</xsgi:env><xsgi:context>{$m}</xsgi:context>{$result[4]}</xsgi:response>
		else
			let $set-headers := for $header in $result[3]/*
					return
						response:set-header(name($header), string($header)) 
			let $set-status := response:set-status-code($result[2])
			return
				$result[4]
};

declare function xsgi:model($xpath){
	let $model  := <xsgi:response>{util:eval($xpath)}</xsgi:response>
	let $format := request:get-parameter('format',())
	return
	if ($format eq 'json') then
		let $content-type := util:declare-option("exist:serialize", "media-type=application/json")
		return
			<xsgi:response>{json:xml-to-json($model/.)}</xsgi:response> (: NOTE- this is a hack :)
	else
		$model
};

declare function xsgi:view($view, $model as xs:string, $content-type){
	let $m := util:eval($model)
	let $debug  := request:get-parameter('debug',())	
	let $content-type := util:declare-option("exist:serialize", concat("media-type=",$content-type))
    return
		if($debug) then
	   		<xsgi:response><xsgi:env>{xsgi:env()}</xsgi:env><xsgi:context>{$m}</xsgi:context>{xsgi:env()}{util:eval-inline($m, util:serialize($view,()) )}</xsgi:response>
		else
      		util:eval-inline($m, util:serialize($view,()) )
};

declare function xsgi:env(){
let $request_data    := request:get-data()
let $request_method  := request:get-method()
let $path_info       := request:get-path-info()
let $request_uri     := request:get-uri()
let $query_string    := request:get-query-string()
let $server_name     := request:get-server-name()
let $server_port     := request:get-server-port()
let $http_vars       := for $header in request:get-header-names()[contains(.,'HTTP_')]
                        return
                            <header name="{$header}">{request:get-header($header)}</header>
let $http_params       := for $param in request:get-parameter-names()
                        return
                            <param name="{$param}">{request:get-parameter($param,())}</param>

let $server_protocol := 'http'
return
    <xsgi:env>
        <request_method>{$request_method}</request_method>
        <path_info>{$path_info}</path_info>
        <request_uri>{$request_uri}</request_uri>
        <query_string>{$query_string}</query_string>
        <server_name>{$server_name}</server_name>
        <server_port>{$server_port}</server_port>
        <http_vars>{$http_vars}</http_vars>
        <http_params>{$http_params}</http_params>
        <server_protocol>{$server_protocol}</server_protocol>
        <xsgi:version>{$xsgi:version}</xsgi:version>
        <xsgi:url_scheme></xsgi:url_scheme>
        <xsgi:input>{$request_data}</xsgi:input>
        <xsgi:errors></xsgi:errors>
    </xsgi:env>
};
